<template lang="pug">
.lis-specimen
  .lis-specimen__form
    mt-form(
      v-bind="editFormProps"
      ref="formRef"
    )
  .lis-specimen__footer
    slot(
      name="footer"
    )
PatientEdit(v-model="showPatientEdit")
barCode(v-model="baeCodeShow" :barcodeData="barcodeList")
cancellation(v-model="cancellationShow" :selectionRow="props.selectionRow")
</template>

<script setup lang="ts">
import {
  type FormItemProps,
  type EditFormProps,
  Form,
  Input,
  Checkbox,
} from "@scmt/common-components";
import {
  type ApiBasedOption,
  type ApiBasedOptions,
  useApi,
} from "@scmt/core-api";
import type {
  SpecimenEntity,
  SpecimenProjectEntity,
} from "@scmt/api-lis-specimen";
import { PatientEdit } from "@scmt/common-api-components";
import { useNotify, Select, Button } from "@scmt/common-components";
import barCode from "../../specimen/collection/compoments/barCode.vue";
import cancellation from "../collection/compoments/cancellation.vue";

import { useUser } from "@scmt/common-store";
import { useRequest } from "@scmt/common-hooks";
import { specimenStatusOptions } from "@scmt/api-common/src/specimen/constants";
import { ESpecimenStatus } from "@scmt/api-common";

//添加 Props属性
const props = defineProps({
  selectEquipment: { type: Object as PropType<SpecimenEntity>, default: {} },
  instrumentId: {
    type: String,
    default: "",
  },
  projectresults: {
    type: Array as PropType<SpecimenProjectEntity[]>,
    default: () => [],
  },
  selectionRow: {
    type: Array as PropType<Object[]>,
    default: () => [],
  },
  buttonShow: {
    type: Boolean as PropType<boolean>,
    default: () => false,
  },
  specimenStatus: {
    type: Boolean as PropType<boolean>,
    default: () => false,
  },
});

const $api = useApi();

const editingObj = ref<SpecimenEntity>($api.lis.specimen.$$createEntity());
const formRef = ref<null | InstanceType<typeof Form>>(null);
const showPatientEdit = ref(false);

const $notify = useNotify();
const emit = defineEmits(["message-to-parent"]);
const baeCodeShow = ref(false);
const cancellationShow = ref(false);
const barcodeList = ref([]);
const search = ref("");
const lisdefineModel = defineModel();
const user = useUser();

const { request, data, loadingMap } = useRequest(
  {
    listDoctorAsOptions: (val: string) =>
      $api.user.listDoctorAsOptions({ officeId: val }),
    getSeriaNumberCode: async (val: string) => {
      $api.bdm.customerEncodingRules
        .getCustomerEncodingRulesByCodeId(val)
        .then((res) => {
          editingObj.value.barcode = res;
          editingObj.value.state = ESpecimenStatus.Done;
          editingObj.value.barcodeGeneratesId = user.userId;
        });
    },
    listByOfficeIdAsOptions: (val: string) => {
      return $api.osm.ward.listByOfficeIdAsOptions(val);
    },
    listByWardIdAsOptions: (wardId: string) => {
      return $api.osm.bed.listByWardIdAsOptions({
        wardId,
        useFlag: 0,
      });
    },
    patients: async (keyword: string) => {
      return $api.patient.queryAsOptions({ keyword, pageNum: 1, pageSize: 10 });
    },
    save: async (model: SpecimenEntity) => {
      model.specimenProjectList = props.projectresults;
      model.deviceId = props.instrumentId;
      return $api.lis.specimen.add(model).then(() => {
        $notify.success("保存成功");
        emit("message-to-parent", "save");
      });
    },
    specimenList: () => {
      return $api.lis.specimen
        .list({
          keyword: search.value || "test",
        })
        .then((res) => {
          if (res && res.length > 0) {
            editingObj.value = $api.lis.specimen.$$createEntity(res[0]);
            lisdefineModel.value = $api.lis.specimen.$$createEntity(res[0]);
          } else {
            editingObj.value = $api.lis.specimen.$$createEntity({});
            $notify.error("无查询结果!!!");
          }
        });
    },
    categoryList: () => {
      return $api.lis.specimen.category.listAsOptions();
    },
  },
  {
    categoryList: [] as ApiBasedOptions,
  }
);

const queryPatients = (keyword: string) => {
  return request("patients", keyword);
};

const empty = () => {
  search.value = "";
};

const formItems = computed<FormItemProps[]>(() =>
  [
    {
      prop: "barcode",
      label: "标本条码",
      disabled: true,
      render: () =>
        h(
          "div",
          {
            style: {
              display: "flex",
              alignItems: "center",
              width: "100%",
            },
          },
          [
            h(Input, {
              placeholder: "请输入标本条码",
              disabled: true,
              modelValue: editingObj.value.barcode,
            }),
            h(Button, {
              label: "生成",
              type: "primary",
              loading: loadingMap.getSeriaNumberCode,
              disabled: Boolean(props.buttonShow || props.selectEquipment.id),
              style: {
                flexShrink: 0,
                marginLeft: "var(--mt-margin)",
              },
              onClick: () => {
                request("getSeriaNumberCode", 3);
              },
            }),
          ]
        ),
    },
    {
      prop: "state",
      label: "标本状态",
      span: 24,
      as: "select",
      disabled: true,
      options: {
        options: specimenStatusOptions,
      },
    },
    {
      prop: "patientName",
      label: "患者姓名",
      required: true,
      render: () => {
        return h(
          "div",
          {
            style: {
              display: "flex",
              alignItems: "center",
              width: "100%",
            },
          },
          [
            h(Select, {
              modelValue: editingObj.value.patientId,
              style: {
                flex: 1,
              },
              onSelect: (val: string) => {
                Object.assign(editingObj.value, {
                  patientId: val?.value,
                  patientName: val?.label,
                  sex: val?._raw?.sex,
                  age: val?._raw?.age,
                });
              },
              remoteMethod: queryPatients,
              render: "patient-table",
              placeholder: "请选择患者",
              disabled: Boolean(props.buttonShow || props.selectEquipment.id),
            }),
            h(Button, {
              label: "快速建档",
              type: "primary",
              disabled: Boolean(props.buttonShow || props.selectEquipment.id),
              style: {
                flexShrink: 0,
                marginLeft: "var(--mt-margin)",
              },
              onClick: () => {
                showPatientEdit.value = true;
              },
            }),
          ]
        );
      },
    },
    {
      prop: "sex",
      label: "性别年龄",
      render: () => {
        return h(
          "div",
          {
            style: {
              display: "flex",
              alignItems: "center",
              width: "100%",
            },
          },
          [
            h(Select, {
              modelValue: editingObj.value.sex,
              style: {
                flex: 1,
              },
              onSelect: (val: string) => {
                Object.assign(editingObj.value, {
                  sex: val,
                });
              },
              placeholder: "请选择性别",
              disabled: true,
              options: [
                {
                  label: "男",
                  value: "男",
                },
                {
                  label: "女",
                  value: "女",
                },
              ],
            }),
            h(Input, {
              modelValue: editingObj.value.age,
              appendText: "岁",
              style: {
                flex: 1,
                marginLeft: "var(--mt-margin)",
              },
              placeholder: "请输入年龄",
              disabled: true,
            }),
          ]
        );
      },
    },
    {
      prop: "applicationProject",
      label: "检查项目",
      required: true,
      as: "select",
      options: {
        remoteMethod: (keyword: string) =>
          $api.lis.portfolioProject.queryAsOptions({
            keyword,
            pageNum: 1,
            pageSize: 10,
          }),
        tableColumns: [
          {
            label: "项目编码",
            prop: "code",
            width: 100,
          },
          {
            label: "项目名称",
            prop: "name",
            width: 100,
          },
          {
            label: "计价单位",
            prop: "price",
            width: 100,
          },
        ],
        onSelect: (val: any) => {
          if (val) {
            Object.assign(editingObj.value, {
              applicationProject: val.name,
              applicationProjectId: val.id,
              specimenTypeId: val.specimenTypeId,
              price: val.price,
            });
            editingObj.value.specimenTypeName =
              data.categoryList.find((i) => i.value == val.specimenTypeId)
                ?.label ?? "";
          }
        },
      },
      disabled: Boolean(props.buttonShow || props.selectEquipment.id),
    },
    {
      prop: "specimenTypeId",
      label: "标本类型",
      required: false,
      as: "select",
      disabled: true,
      options: {
        options: data.categoryList,
      },
    },
    {
      prop: "source",
      label: "业务来源",
      required: false,
      options: {
        loadMethod: () => $api.dict.item.listAsOptions("patient-type"),
      },
      render: () => {
        return h(
          "div",
          {
            style: {
              display: "flex",
              alignItems: "center",
              width: "100%",
            },
          },
          [
            h(Select, {
              modelValue: editingObj.value.source,
              placeholder: "请选择业务来源",
              disabled: Boolean(props.buttonShow || props.selectEquipment.id),
              loadMethod: () => $api.dict.item.listAsOptions("patient-type"),
              "onUpdate:modelValue": (val: any) => {
                Object.assign(editingObj.value, {
                  source: val,
                });
              },
            }),
            h(Checkbox, {
              modelValue: editingObj.value.urgent,
              style: {
                flexShrink: 0,
                marginLeft: "var(--mt-margin)",
              },
              disabled: Boolean(props.buttonShow || props.selectEquipment.id),
              trueValue: 1,
              falseValue: 0,
              label: "加急",
              "onUpdate:modelValue": (val: any) => {
                Object.assign(editingObj.value, {
                  urgent: val,
                });
              },
            }),
          ]
        );
      },
    },
    {
      prop: "billingTime",
      label: "开单时间",
      required: false,
      disabled: Boolean(props.buttonShow || props.selectEquipment.id),
      as: "date",
    },
    {
      prop: "billingDepartment",
      label: "开单科室",
      required: false,
      as: "select",
      disabled: Boolean(props.buttonShow || props.selectEquipment.id),
      options: {
        render: "office-table",
        loadMethod: () => $api.upms.org.listAsOptions(),
      },
    },
    {
      prop: "billingDoctor",
      label: "开单医生",
      required: false,
      as: "select",
      disabled: Boolean(props.buttonShow || props.selectEquipment.id),
      options: {
        render: "doctor-table",
        loadMethod: () => $api.user.listDoctorAsOptions({ officeId: "" }),
      },
    },
    {
      prop: "collectionId",
      label: "采集医生",
      required: false,
      as: "select",
      disabled: true,
      options: {
        loadMethod: () => $api.user.listDoctorAsOptions({ officeId: "" }),
      },
    },
    {
      prop: "collectionTime",
      label: "采集时间",
      required: false,
      as: "date",
      disabled: true,
    },
    {
      prop: "sampleContainer",
      label: "试管名称",
      required: false,
      visible: props.specimenStatus,
      disabled: true,
    },
    {
      prop: "inspector",
      label: "检验人",
      required: false,
      as: "select",
      visible: !props.specimenStatus,
      options: {
        options: data.listDoctorAsOptions,
      },
    },
    {
      prop: "inspectionTime",
      label: "检验日期",
      required: false,
      visible: !props.specimenStatus,
      as: "date",
    },
  ].filter((i) => i.visible === void 0 || i.visible)
);
const editFormProps = computed<EditFormProps>(() => {
  const editProps: EditFormProps = {
    model: editingObj.value,
    items: formItems.value,
    columns: 1,
  };
  return editProps;
});
const validate = (
  callback?: (valid: boolean, model: any) => Promise<void> | void
) => {
  formRef.value?.validate((valid) => {
    typeof callback === "function" && callback(valid, editingObj.value);
  });
};

onMounted(() => {
  request("categoryList", {
    onSuccess: (categoryList) => {
      // 如何已选择检查项目
      if (editingObj.value?.specimenTypeId) {
        editingObj.value.specimenTypeName =
          categoryList.find((i) => i.value == editingObj.value?.specimenTypeId)
            ?.label ?? "";
      }
    },
  });
});

defineExpose({ validate, empty, request });
watch(
  () => props.selectEquipment,
  (item) => {
    if (item) {
      editingObj.value = $api.lis.specimen.$$createEntity(item);
    } else {
      editingObj.value = $api.lis.specimen.$$createEntity({});
    }
  },
  {
    immediate: true,
    deep: true,
  }
);

watch(
  () => editingObj.value.billingDepartment,
  (item) => {
    if (item) {
      request("listDoctorAsOptions", "");
      request("listByOfficeIdAsOptions", item);
    }
  },
  {
    immediate: true,
  }
);
watch(
  () => props.instrumentId,
  (item) => {
    if (item) {
      Object.assign(editingObj.value, {
        deviceId: item,
      });
    }
  },
  {
    immediate: true,
  }
);
</script>

<style lang="less" scoped>
.lis-specimen {
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;

  &__query {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    margin-bottom: var(--mt-margin-large);

    &-select {
      flex: 1;
      overflow: hidden;
    }

    &-button {
      flex-shrink: 0;
      margin-left: var(--mt-margin-large);
    }
  }

  &__form {
    overflow: hidden;
  }

  &__footer {
    flex-shrink: 0;
  }
}

.actions {
  display: flex;
  justify-content: flex-end;
  margin-bottom: var(--mt-margin-large);
}
</style>
